package com.cygsunri.income.service;

import com.cygsunri.common.service.CommonDataService;
import com.cygsunri.income.entity.*;
import com.cygsunri.measurement.entity.Flag;
import com.cygsunri.measurement.entity.MeasurementValue;
import com.cygsunri.util.DateUtil;
import com.cygsunri.util.TimeUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;

@Slf4j
@Service
public class IncomeService {

    @Autowired
    private IncomePlanMappingService incomePlanMappingService;
    @Autowired
    private CommonDataService commonDataService;
    @Autowired
    private IncomeCacheService incomeCacheService;
    @Autowired
    private IncomePlanService incomePlanService;
    @Autowired
    private IncomeTimeService incomeTimeService;

    /**
     * 统计收益缓存
     */
    public void updateCache(String date) {
        long a = System.currentTimeMillis();
        List<IncomePlanMapping> list = incomePlanMappingService.getIncomePlanMappingList(date);
        for (IncomePlanMapping incomePlanMapping : list) {
            updateCache(date, incomePlanMapping);
        }
        log.info("日期：{}， 收益缓存耗时：{} ms", date, System.currentTimeMillis() - a);
    }

    /**
     * 统计指定id的策略
     */
    public void updateCache(String date, String id) {
        long a = System.currentTimeMillis();
        IncomePlanMapping incomePlanMapping = incomePlanMappingService.getIncomePlanMapping(id);
        if (incomePlanMapping == null) {
            log.warn("未找到策略，id：{}", id);
            return;
        }
        updateCache(date, incomePlanMapping);
        log.info("日期：{}, 策略id：{}, 收益缓存耗时：{} ms", date, id, System.currentTimeMillis() - a);
    }

    /**
     * 统计指定策略
     */
    private void updateCache(String date, IncomePlanMapping incomePlanMapping) {
        IncomePlan incomePlan = incomePlanService.getIncomePlanByID(incomePlanMapping.getIncomePlan());
        MeasurementValue m = MeasurementValue.fromNameMode(incomePlanMapping.getPsrID(), incomePlanMapping.getDataName()).setFlag(Flag.getFlag(Flag.PERIOD_DIFF));
        String[] types = incomePlanMapping.getType().split("\\|");
        for (String t : types) {
            Integer type = Integer.parseInt(t);
            switch (Objects.requireNonNull(IncomeCacheType.find(type))) {
                case INTERVAL_CHARGE:
                case INTERVAL_DISCHARGE:
                    intervalCalc(date, type, m, incomePlan);
                    break;
                case INTERVAL_CHARGE_BILLS:
                case INTERVAL_DISCHARGE_BILL:
                    intervalBillsCalc(date, type, m, incomePlan);
                    break;
                case DAY_CHARGE:
                case DAY_DISCHARGE:
                case DAY_CHARGE_BILLS:
                case DAY_DISCHARGE_BILLS:
                    dayCalc(date, type, m, incomePlan);
                    break;
                case MONTH_CHARGE:
                case MONTH_DISCHARGE:
                case MONTH_CHARGE_BILLS:
                case MONTH_DISCHARGE_BILLS:
                    monthCalc(date, type, m, incomePlan);
                    break;
                default:
                    return;
            }
        }
    }

    /**
     * 计算分段缓存
     */
    private void intervalCalc(String date, Integer type, MeasurementValue m, IncomePlan incomePlan) {
        for (IncomeTime incomeTime : incomeTimeService.getIncomeTimeListByIncomePlanId(incomePlan.getId())) {
            m = commonDataService.getStatisticValue(m, TimeUtil.convertTime(date + " " + incomeTime.getBeginTime()), TimeUtil.convertTime(date + " " + incomeTime.getEndTime()));
            if (m.isInValid()) {
                m.setQuality(MeasurementValue.Quality.Normal);
                continue;
            }
            IncomeCache incomeCache = new IncomeCache()
                    .setDate(date)
                    .setTime(incomeTime.getEndTime())
                    .setPsrID(m.getO().getId())
                    .setName(m.getName())
                    .setData(m.getData())
                    .setCacheType(type)
                    .setPlanName(incomePlan.getName());
            incomeCacheService.saveIncomeCache(incomeCache);
        }
    }

    /**
     * 计算分段电费缓存
     */
    private void intervalBillsCalc(String date, Integer type, MeasurementValue m, IncomePlan incomePlan) {
        for (IncomeTime incomeTime : incomeTimeService.getIncomeTimeListByIncomePlanId(incomePlan.getId())) {
            m = commonDataService.getStatisticValue(m, TimeUtil.convertTime(date + " " + incomeTime.getBeginTime()), TimeUtil.convertTime(date + " " + incomeTime.getEndTime()));
            //if (m.isInValid()) return;
            if (m.isInValid()) {
                m.setQuality(MeasurementValue.Quality.Normal);
                continue;
            }
            Integer month = Integer.valueOf(DateUtil.parse(date).getMonth().getValue());
            IncomeCache incomeCache = new IncomeCache()
                    .setDate(date)
                    .setTime(incomeTime.getEndTime())
                    .setPsrID(m.getO().getId())
                    .setName(m.getName())
                    .setData(m.getData() * (month >= 7 && month <= 9 && incomeTime.getLevel2_Price() != null ? incomeTime.getLevel2_Price() : incomeTime.getLevel1_Price()))
                    .setCacheType(type)
                    .setPlanName(incomePlan.getName());
            incomeCacheService.saveIncomeCache(incomeCache);
        }
    }

    /**
     * 计算日缓存
     */
    private void dayCalc(String date, Integer type, MeasurementValue m, IncomePlan incomePlan) {
        IncomeCache incomeCache = new IncomeCache()
                .setDate(date)
                .setPsrID(m.getO().getId())
                .setName(m.getName())
                .setCacheType(type)
                .setPlanName(incomePlan.getName());
        Double value = incomeCacheService.getDaySum(m.getO().getId(), m.getName(), date, type - 4, incomePlan.getName());
        if (value != null) {
            incomeCache.setData(value);
            incomeCacheService.saveIncomeCache(incomeCache);
        }
    }

    /**
     * 计算月缓存
     */
    private void monthCalc(String date, Integer type, MeasurementValue m, IncomePlan incomePlan) {
        IncomeCache incomeCache = new IncomeCache()
                .setDate(date)
                .setPsrID(m.getO().getId())
                .setName(m.getName())
                .setCacheType(type)
                .setPlanName(incomePlan.getName());
        List<String> days = DateUtil.getDays(date.substring(0, 7));
        Double value = incomeCacheService.getMonthSum(m.getO().getId(), m.getName(), days.get(0), days.get(days.size() - 1), type - 4, incomePlan.getName());
        if (value != null) {
            incomeCache.setData(value);
            incomeCacheService.saveIncomeCache(incomeCache);
        }
    }
}
